<template>
  <el-select v-model="localValue" placeholder="请选择" v-bind="$attrs">
    <el-option v-if="hasDefault" :label="defaultOptionName" value="" />
    <el-option
      v-for="item in options"
      :key="item[valueName]"
      :label="item[labelName]"
      :value="item[valueName]"
      v-on="$listeners"
    />
  </el-select>
</template>

<script>
import { getOption } from '@/api/choose'

export default {
  name: 'choice',
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    url: {
      type: String,
      default: '/system/dict/parent'
    },
    parentId: {
      type: String,
      default: null
    },
    value: {
      type: [String, Number, Array],
      required: true
    },
    labelName: {
      type: String,
      default: 'name'
    },
    valueName: {
      type: String,
      default: 'id'
    },
    defaultOptionName: {
      type: String,
      default: '请选择'
    },
    hasDefault: {
      type: Boolean,
      default: true
    },
    where: {
      type: Object,
      default: null
    },
    localData: {
      type: Array,
      default: null
    },
    cacheKey: {
      type: String,
      default: ''
    },
    canCached: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      options: []
    }
  },
  computed: {
    localValue: {
      get() {
        return this.value
      },
      set(val) {
        this.$emit('change', val)
      }
    }
  },
  watch: {
    localData(newVal) {
      if (newVal && newVal.length > 0) {
        this.options = this.localData
      } else {
        this.reload()
      }
    }
  },
  mounted() {
    let cache = ''
    if (this.cacheKey) {
      cache = this.$store.getters.loadCache(this.cacheKey)
      if (cache) {
        this.options = cache
        return
      }
    }
    if (this.url) {
      const requestURL = this.formatterUrl()
      this.setOption(requestURL, this.options)
    }
  },
  methods: {
    formatterUrl() {
      if (this.parentId) {
        return this.url + '/' + this.parentId
      }
      return this.url
    },
    setOption(url, variable) {
      getOption(url, this.where).then(res => {
        variable.push.apply(variable, res.data)
        if (this.canCached) {
          this.$store.commit('saveCache', { key: this.cacheKey, value: res.data })
        }
      })
    },
    reload() {
      this.options = []
      this.setOption(this.url, this.options)
    },
    getLabelName(val) {
      const obj = this.options.find(item => {
        return item[this.valueName] === val
      })
      return obj[this.labelName]
    }
  }
}
</script>

<style>

</style>
